﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using HslCommunication;
using HslCommunication.ModBus;
using System.Threading;
using System.Collections;
using HslCommunication.Controls;
using VzClientSDKDemo;
using System.Runtime.InteropServices;
using System.IO;


namespace PLC_Communication
{
    public partial class FormModbus : Form
    {

        private const int MSG_PLATE_INFO = 0x901;
        private const int MSG_DEVICE_INFO = 0x902;

        private int m_nPlayHandle = 0;
        private int m_nPlayHandle2 = 0;

        private string m_sAppPath;

        System.Timers.Timer resetrecordtime;

        public IntPtr hwndMain;

        int m_nLastLEDLevel;


        private Color m_originalColor;
        private bool m_bFirst;
        private bool m_bFindDev;

        private VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK m_PlateResultCB = null;
        private VzClientSDK.VZLPRC_FIND_DEVICE_CALLBACK_EX find_DeviceCB = null;
        private VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK m_PlateResultCB2 = null;

        public FormModbus()
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
        }

        public ModBusTcpClient busTcpClient { get; set; }

        System.Timers.Timer timer; //定义Timer类

        public delegate void SetDateTime();////定义时钟委托
        public delegate void Begin_Read();//实时采集 

        //定义全局变量
        public bool PLC_connected = false;
        public bool timer_Stared = false;
        public bool isReading = true;


        private void FormSiemens_Load(object sender, EventArgs e)
        {
            panel2.Enabled = false;
            Thread thread = new Thread(new ThreadStart(DateTimeInfo));
            thread.IsBackground = true;
            thread.Start(); //显示当前时间            
            userCurve1.SetLeftCurve("A", new float[0], Color.Tomato);


            VzClientSDK.VzLPRClient_Setup();

            hwndMain = this.Handle;

            m_sAppPath = System.IO.Directory.GetCurrentDirectory();
            m_originalColor = pictureBox1.BackColor;
            m_bFirst = true;
            m_bFindDev = false;
            radledauto.Checked = true;


            this.listView1.Columns.Add("设备IP");
            this.listView1.Columns.Add("车牌号");
            this.listView1.Columns.Add("入口时间");
            this.listView1.View = System.Windows.Forms.View.Details;
            this.listView1.FullRowSelect = true;
            this.listView1.GridLines = true;
            listView1.Columns[0].Width = 80;
            listView1.Columns[1].Width = 60;
            listView1.Columns[2].Width = 60;

            // outputbox.SelectedIndex = 0;
        }
        /// <summary>
        /// 初始化Timer控件
        /// </summary>
        private void InitTimer()
        {
            //设置定时间隔(毫秒为单位)
            int interval = Convert.ToInt16(textBox10.Text);
            timer = new System.Timers.Timer(interval);
            //设置执行一次（false）还是一直执行(true)
            timer.AutoReset = true;
            //设置是否执行System.Timers.Timer.Elapsed事件
            timer.Enabled = true;
            //绑定Elapsed事件
            timer.Elapsed += new System.Timers.ElapsedEventHandler(TimerUp);
        }

        /// <summary>
        /// Timer类执行定时到点事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TimerUp(object sender, System.Timers.ElapsedEventArgs e) //实时采集
        {
            try
            {
                // currentCount += 1;
                this.Invoke(new Begin_Read(PLC_Read));
            }
            catch (Exception ex)
            {
                toolStripStatusLabel1.Text = "执行定时到点事件失败:" + ex.Message;
            }
        }

        private void FormSiemens_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (timer_Stared)
            {
                timer.Stop();
            }
            if (PLC_connected)
            {
                busTcpClient.ConnectClose();
            }

        }

        /// <summary>
        /// 统一的读取结果的数据解析，显示
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="result"></param>
        /// <param name="address"></param>
        /// <param name="textBox"></param>
        private void readResultRender<T>(OperateResult<T> result, string address, TextBox textBox)
        {
            if (result.IsSuccess)
            {
                textBox.AppendText(DateTime.Now.ToString("[HH:mm:ss] ") + string.Format("[{address}] {result.Content}{Environment.NewLine}"));
            }
            else
            {
                toolStripStatusLabel1.Text = DateTime.Now.ToString("[HH:mm:ss] ") + string.Format("[{address}] 读取失败{Environment.NewLine}原因：{result.ToMessageShowString()}");
            }
        }

        /// <summary>
        /// 统一的数据写入的结果显示
        /// </summary>
        /// <param name="result"></param>
        /// <param name="address"></param>
        private void writeResultRender(OperateResult result, string address)
        {
            if (result.IsSuccess)
            {
                toolStripStatusLabel1.Text = DateTime.Now.ToString("[HH:mm:ss] ") + string.Format("[{address}] 写入成功");
            }
            else
            {
                toolStripStatusLabel1.Text = DateTime.Now.ToString("[HH:mm:ss] ") + string.Format("[{address}] 写入失败{Environment.NewLine}原因：{result.ToMessageShowString()}");
            }
        }


        #region Connect And Close

        private void button1_Click(object sender, EventArgs e)//连接服务器
        {
            System.Net.IPAddress address;
            // 连接
            if (!System.Net.IPAddress.TryParse(textBox1.Text, out address))
            {
                toolStripStatusLabel1.Text = "Ip地址输入不正确！";
                return;
            }
            int port;

            if (!int.TryParse(textBox2.Text, out port))
            {
                toolStripStatusLabel1.Text = "端口输入不正确！";
                return;
            }
            byte station;

            if (!byte.TryParse(textBox15.Text, out station))
            {
                toolStripStatusLabel1.Text = "站号输入不正确！";
                return;
            }

            if(busTcpClient!=null){
                busTcpClient.ConnectClose();
            }           
            busTcpClient = new ModBusTcpClient(textBox1.Text, port, station);

            try
            {
                OperateResult connect = busTcpClient.ConnectServer();
                if (connect.IsSuccess)
                {
                    toolStripStatusLabel1.Text = "连接成功！";
                    button2.Enabled = true;
                    button1.Enabled = false;
                    panel2.Enabled = true;
                    PLC_connected = true;
                    timer_Stared = true;
                    InitTimer(); //启动连续采集
                }
                else
                {
                    toolStripStatusLabel1.Text = "连接失败！";
                }
            }
            catch (Exception ex)
            {
                toolStripStatusLabel1.Text = ex.Message;
            }

        }

        private void button2_Click(object sender, EventArgs e)//断开连接
        {
            // 断开连接
            busTcpClient.ConnectClose();
            button2.Enabled = false;
            button1.Enabled = true;
            panel2.Enabled = false;
            timer.Stop();

        }


        #endregion

        #region 单数据读取测试


        private void button_read_bool_Click(object sender, EventArgs e)
        {
            // 读取bool变量
            readResultRender(busTcpClient.ReadBoolCoil(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }

        private void button_read_short_Click(object sender, EventArgs e)
        {
            // 读取short变量
            readResultRender(busTcpClient.ReadShortRegister(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }

        private void button_read_ushort_Click(object sender, EventArgs e)
        {
            // 读取ushort变量
            readResultRender(busTcpClient.ReadUShortRegister(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }

        private void button_read_int_Click(object sender, EventArgs e)
        {
            // 读取int变量
            readResultRender(busTcpClient.ReadIntRegister(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }
        private void button_read_uint_Click(object sender, EventArgs e)
        {
            // 读取uint变量
            readResultRender(busTcpClient.ReadUIntRegister(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }
        private void button_read_long_Click(object sender, EventArgs e)
        {
            // 读取long变量
            readResultRender(busTcpClient.ReadLongRegister(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }

        private void button_read_ulong_Click(object sender, EventArgs e)
        {
            // 读取ulong变量
            readResultRender(busTcpClient.ReadULongRegister(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }

        private void button_read_float_Click(object sender, EventArgs e)
        {
            // 读取float变量
            readResultRender(busTcpClient.ReadFloatRegister(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }

        private void button_read_double_Click(object sender, EventArgs e)
        {
            // 读取double变量
            readResultRender(busTcpClient.ReadDoubleRegister(ushort.Parse(textBox3.Text)), textBox3.Text, textBox4);
        }

        private void button_read_string_Click(object sender, EventArgs e)
        {
            // 读取字符串
            readResultRender(busTcpClient.ReadStringRegister(ushort.Parse(textBox3.Text), ushort.Parse(textBox5.Text)), textBox3.Text, textBox4);
        }


        #endregion

        #region 单数据写入测试


        private void button24_Click(object sender, EventArgs e)
        {
            // bool写入
            try
            {
                writeResultRender(busTcpClient.WriteOneCoil(ushort.Parse(textBox8.Text), bool.Parse(textBox7.Text)), textBox8.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button22_Click(object sender, EventArgs e)
        {
            // short写入
            // string json2 = "[{\"Adress\":\"0\",\"Value\":\"0066\"}]";
            string json2 = "";

            try
            {
                if (!string.IsNullOrEmpty(json2))
                {
                    List<PLC_Retured_value> Retured_v2 = JsonHelper.DeserializeJsonToList<PLC_Retured_value>(json2);//监控值的反序列化
                    foreach (var item in Retured_v2)
                    {
                        writeResultRender(busTcpClient.WriteRegister(ushort.Parse(item.Adress), ushort.Parse(item.Value)), item.Adress);
                        Thread.Sleep(20);
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(textBox8.Text) && !string.IsNullOrEmpty(textBox7.Text))
                        writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), ushort.Parse(textBox7.Text)), textBox8.Text);

                }

            }
            catch (Exception ex)
            {
                toolStripStatusLabel1.Text = ex.Message;
            }
        }

        private void button21_Click(object sender, EventArgs e)
        {
            // ushort写入
            try
            {
                writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), ushort.Parse(textBox7.Text)), textBox8.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        private void button20_Click(object sender, EventArgs e)
        {
            // int写入
            try
            {
                writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), int.Parse(textBox7.Text)), textBox8.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button19_Click(object sender, EventArgs e)
        {
            // uint写入
            try
            {
                writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), uint.Parse(textBox7.Text)), textBox8.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button18_Click(object sender, EventArgs e)
        {
            // long写入
            try
            {
                writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), long.Parse(textBox7.Text)), textBox8.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button17_Click(object sender, EventArgs e)
        {
            // ulong写入
            try
            {
                writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), ulong.Parse(textBox7.Text)), textBox8.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button16_Click(object sender, EventArgs e)
        {
            // float写入
            try
            {
                writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), float.Parse(textBox7.Text)), textBox8.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button15_Click(object sender, EventArgs e)
        {
            // double写入
            try
            {
                writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), double.Parse(textBox7.Text)), textBox8.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        private void button14_Click(object sender, EventArgs e)
        {
            // string写入
            try
            {
                writeResultRender(busTcpClient.WriteRegister(ushort.Parse(textBox8.Text), textBox7.Text), textBox8.Text);
            }
            catch (Exception ex)
            {
                toolStripStatusLabel1.Text = ex.Message;
            }
        }

        #endregion

        public void PictureMarker(List<PLC_Retured_value> aa)
        {
            int ii = 1;
            foreach (var item in aa)
            {
                if (ii < 10)
                {
                    string name = "userLantern" + ii.ToString();
                    object o = GetType().GetField(name, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase).GetValue(this);
                    string name2 = "label" + (ii + 21).ToString();
                    object o2 = GetType().GetField(name2, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase).GetValue(this);

                    ((Label)o2).Text = "地址:DB" + item.Adress.ToString();
                    if (item.Value == "0001")
                        ((UserLantern)o).LanternBackground = Color.LimeGreen;
                    else
                    if (item.Value == "0000")
                        ((UserLantern)o).LanternBackground = Color.Red;
                    else
                        ((UserLantern)o).LanternBackground = Color.Silver;


                }
                ii++;
            }


        }

        public void DisPlayString_ToJson(string str)//采集数据显示并转Json
        {

            List<PLC_Retured_value> Retured_v = new List<PLC_Retured_value>();
            if (!string.IsNullOrEmpty(str))
            {
                ArrayList array = GetSeparateSubString(str, 4);
                int Read_adress = Convert.ToInt32(textBox6.Text);
                Retured_v.Clear();

                foreach (string arr in array)
                {
                    PLC_Retured_value Retured_value = new PLC_Retured_value();
                    Value_List.Text += "DB地址" + Read_adress + ":  " + arr + " \r\n";

                    Retured_value.Adress = Read_adress.ToString();
                    Retured_value.Value = arr;

                    //实体集合序列化和反序列化

                    Retured_v.Add(Retured_value);

                    Read_adress++;
                }
            }
            string json2 = JsonHelper.SerializeObject(Retured_v); //序列化

            List<PLC_Retured_value> Retured_v2 = JsonHelper.DeserializeJsonToList<PLC_Retured_value>(json2);//监控值的反序列化

            PictureMarker(Retured_v2);  //监控图标变色
        }
        private ArrayList GetSeparateSubString(string txtString, int charNumber) //charNumber为要截取的每段的长度
        {
            ArrayList arrlist = new ArrayList();
            string tempStr = txtString;
            for (int i = 0; i < tempStr.Length; i += charNumber)//首先判断字符串的长度，循环截取，进去循环后首先判断字符串是否大于每段的长度
            {
                if ((tempStr.Length - i) > charNumber)//如果是，就截取
                {
                    arrlist.Add(tempStr.Substring(i, charNumber));
                }
                else
                {
                    arrlist.Add(tempStr.Substring(i));//如果不是，就截取最后剩下的那部分
                }
            }
            return arrlist;
        }

        #region 批量读取测试
        private void button25_Click(object sender, EventArgs e)//读取
        {

            if (!isReading)
            {
                timer.Start();
                button25.Text = "停止";
                isReading = true;
            }
            else
            {
                button25.Text = "开始";
                isReading = false;
                timer.Stop();

            }

        }

        #endregion

        #region 报文读取测试


        private void button26_Click(object sender, EventArgs e)
        {
            try
            {
                OperateResult<byte[]> read = busTcpClient.ReadFromServerCore(HslCommunication.BasicFramework.SoftBasic.HexStringToBytes(textBox13.Text));
                if (read.IsSuccess)
                {
                    textBox11.Text = "结果：" + HslCommunication.BasicFramework.SoftBasic.ByteToHexString(read.Content);
                }
                else
                {
                    MessageBox.Show("读取失败：" + read.ToMessageShowString());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取失败：" + ex.Message);
            }
        }


        #endregion

        #region 定时器读取测试

        // 外加曲线显示

        private Thread thread = null;              // 后台读取的线程
        private int timeSleep = 300;               // 读取的间隔
        private bool isThreadRun = false;          // 用来标记线程的运行状态

        private void button27_Click(object sender, EventArgs e)
        {
            // 启动后台线程，定时读取PLC中的数据，然后在曲线控件中显示

            if (!isThreadRun)
            {
                if (!int.TryParse(textBox14.Text, out timeSleep))
                {
                    toolStripStatusLabel1.Text = "间隔时间格式输入错误！";
                    return;
                }
                button27.Text = "停止";
                isThreadRun = true;
                thread = new Thread(ThreadReadServer);
                thread.IsBackground = true;
                thread.Start();
            }
            else
            {
                button27.Text = "启动";
                isThreadRun = false;
            }
        }

        private void ThreadReadServer()
        {
            while (isThreadRun)
            {
                Thread.Sleep(timeSleep);

                try
                {
                    OperateResult<short> read = busTcpClient.ReadShortRegister(ushort.Parse(textBox12.Text));
                    if (read.IsSuccess)
                    {
                        // 显示曲线
                        if (isThreadRun) Invoke(new Action<short>(AddDataCurve), read.Content);
                    }
                }
                catch (Exception ex)
                {
                    toolStripStatusLabel1.Text = "读取失败：" + ex.Message;
                }

            }
        }


        private void AddDataCurve(short data)
        {
            userCurve1.AddCurveData("A", data);
        }


        #endregion

        private void PLC_Read()
        {
            try

            {
                OperateResult<byte[]> read = busTcpClient.ReadRegister(ushort.Parse(textBox6.Text), ushort.Parse(textBox9.Text));
                if (read.IsSuccess)
                {
                    Value_List.Text = "";
                    string returned_value = HslCommunication.BasicFramework.SoftBasic.ByteToHexString(read.Content);
                    DisPlayString_ToJson(returned_value);
                }
                else
                {
                    toolStripStatusLabel1.Text = "读取失败：" + read.ToMessageShowString();
                }
            }
            catch (Exception ex)
            {
                toolStripStatusLabel1.Text = "读取失败：" + ex.Message;
            }

        }
        private void DateTimeInfo()
        {
            while (true)
            {
                SetDateTime setDate = new SetDateTime(
                delegate
                {
                    toolStripStatusLabel2.Text = DateTime.Now.ToString();
                });
                setDate();
                Thread.Sleep(1000);
            }
            // ReSharper disable once FunctionNeverReturns
        }

        private void startsearchdev_Click(object sender, EventArgs e)
        {
            VzClientSDK.VZLPRClient_StopFindDevice();

            dev_treeview.Nodes.Clear();
            find_DeviceCB = new VzClientSDK.VZLPRC_FIND_DEVICE_CALLBACK_EX(FIND_DEVICE_CALLBACK_EX);
            int ret = VzClientSDK.VZLPRClient_StartFindDeviceEx(find_DeviceCB, IntPtr.Zero);
            if (ret == 0)
            {
                m_bFindDev = true;
            }
        }

        private void FIND_DEVICE_CALLBACK_EX(string pStrDevName, string pStrIPAddr, ushort usPort1, ushort usPort2, uint SL, uint SH, string netmask, string gateway, IntPtr pUserData)
        {
            string pStrDev = pStrIPAddr.ToString() + ":" + usPort1.ToString();
            string serialNO = SL.ToString() + ":" + SH.ToString() + ":" + netmask + ":" + gateway;

            VzClientSDK.VZ_LPR_DEVICE_INFO device_info = new VzClientSDK.VZ_LPR_DEVICE_INFO();
            device_info.device_ip = pStrDev;
            device_info.serial_no = serialNO;

            int size = Marshal.SizeOf(device_info);
            IntPtr intptr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(device_info, intptr, true);

            Win32API.PostMessage(hwndMain, MSG_DEVICE_INFO, (int)intptr, 0);
        }

        private void stopsearchdev_Click(object sender, EventArgs e)
        {
            VzClientSDK.VZLPRClient_StopFindDevice();
            if (m_bFindDev)
            {
                m_bFindDev = false;
            }
        }

        private void btnNetCfg_Click(object sender, EventArgs e)
        {
            if (dev_treeview.SelectedNode != null)
            {
                string ip = dev_treeview.SelectedNode.Text.ToString();
                string serialNO = dev_treeview.SelectedNode.Tag.ToString();

                string[] arrIP = ip.Split(new char[] { ':' });
                string[] arrSerial = serialNO.Split(new char[] { ':' });

                uint SL = uint.Parse(arrSerial[0]);
                uint SH = uint.Parse(arrSerial[1]);

                NetCfg_Form from = new NetCfg_Form();
                from.StartPosition = FormStartPosition.CenterScreen;
                from.SetNetParam(arrIP[0], SL, SH, arrSerial[2], arrSerial[3]);
                from.Show();
            }
            else
            {

                toolStripStatusLabel1.Text = "请选择搜索设备列表中的设备";
            }
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            short nPort = Int16.Parse(txtPort.Text);

            int handle = VzClientSDK.VzLPRClient_Open(txtIP.Text, (ushort)nPort, txtUserName.Text, txtPwd.Text);
            if (handle == 0)
            {
                toolStripStatusLabel1.Text = txtIP.Text + "摄像头打开失败";
                return;
            }
            toolStripStatusLabel1.Text = txtIP.Text + "摄像头打开成功";
            TreeNode node = new TreeNode(txtIP.Text);
            node.Tag = handle;
            treeDevice.Nodes.Add(node);

            treeDevice.SelectedNode = node;
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = lprHandle.ToString() + "请选择一台列表中的设备";
                return;
            }

            if (lprHandle == GetPicBox1Handle())
            {
                if (m_nPlayHandle > 0)
                {
                    int ret = VzClientSDK.VzLPRClient_StopRealPlay(m_nPlayHandle);
                    m_nPlayHandle = 0;
                }

                Pic1Close();
                Pic2Close();
            }
            else
            {
                if (m_nPlayHandle2 > 0)
                {
                    int ret = VzClientSDK.VzLPRClient_StopRealPlay(m_nPlayHandle2);
                    m_nPlayHandle2 = 0;
                }

                Pic3Close();
                Pic4Close();
            }

            VzClientSDK.VzLPRClient_Close(lprHandle);
            treeDevice.Nodes.Remove(treeDevice.SelectedNode);
        }

        private int GetSeleHandle()
        {
            int handle = 0;

            if (treeDevice.SelectedNode != null)
            {
                string sHandle = treeDevice.SelectedNode.Tag.ToString();
                handle = Int32.Parse(sHandle);
            }

            return handle;
        }

        private int GetPicBox1Handle()
        {
            int handle = 0;

            if (pictureBox1.Tag != null)
            {
                string sHandle = pictureBox1.Tag.ToString();
                handle = Int32.Parse(sHandle);
            }

            return handle;
        }

        private delegate void Pic1CloseThread();
        public void Pic1Close()
        {
            Pic1CloseThread Pic1CloseDelegate = delegate ()
            {
                pictureBox1.Image = null;
                pictureBox1.Refresh();
                pictureBox1.Tag = 0;
            };
            pictureBox1.Invoke(Pic1CloseDelegate);
        }

        //关闭第二个窗口
        private delegate void Pic2CloseThread();
        public void Pic2Close()
        {
            Pic2CloseThread Pic2CloseDelegate = delegate ()
            {
                pictureBox2.Image = null;
                pictureBox2.Refresh();
            };
            pictureBox2.Invoke(Pic2CloseDelegate);
        }

        //关闭第三个窗口
        private delegate void Pic3CloseThread();
        public void Pic3Close()
        {
            Pic2CloseThread Pic3CloseDelegate = delegate ()
            {
                pictureBox3.Image = null;
                pictureBox3.Refresh();
                pictureBox3.Tag = 0;
            };
            pictureBox3.Invoke(Pic3CloseDelegate);
        }

        //关闭第四个窗口
        private delegate void Pic4CloseThread();
        public void Pic4Close()
        {
            Pic1CloseThread Pic4CloseDelegate = delegate ()
            {
                pictureBox4.Image = null;
                pictureBox4.Refresh();
            };

            pictureBox4.Invoke(Pic4CloseDelegate);
        }

        private void btnManual_Click(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            if (lprHandle > 0)
            {
                VzClientSDK.VzLPRClient_ForceTrigger(lprHandle);
            }
        }

        private void startoutputbtn_Click(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            if (lprHandle == GetPicBox1Handle() || lprHandle == GetPicBox3Handle())
            {
                toolStripStatusLabel1.Text = "该设备已经输出在视频窗口中，请先停止。";
                return;
            }

            if (m_bFirst)
            {
                pictureBox1.Image = null;
                if (m_nPlayHandle > 0)
                {
                    VzClientSDK.VzLPRClient_StopRealPlay(m_nPlayHandle);
                    m_nPlayHandle = 0;
                }

                int lprHandle1 = GetPicBox1Handle();
                if (lprHandle1 > 0)
                {
                    VzClientSDK.VzLPRClient_SetPlateInfoCallBack(lprHandle1, null, IntPtr.Zero, 0);
                }

                m_nPlayHandle = VzClientSDK.VzLPRClient_StartRealPlay(lprHandle, pictureBox1.Handle);
                pictureBox1.Tag = lprHandle;

                // 设置车牌识别结果回调
                m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
                VzClientSDK.VzLPRClient_SetPlateInfoCallBack(lprHandle, m_PlateResultCB, IntPtr.Zero, 1);
            }
            else
            {
                pictureBox3.Image = null;
                if (m_nPlayHandle2 > 0)
                {
                    VzClientSDK.VzLPRClient_StopRealPlay(m_nPlayHandle2);
                    m_nPlayHandle2 = 0;
                }

                int lprHandle2 = GetPicBox3Handle();
                if (lprHandle2 > 0)
                {
                    VzClientSDK.VzLPRClient_SetPlateInfoCallBack(lprHandle2, null, IntPtr.Zero, 0);
                }

                m_nPlayHandle2 = VzClientSDK.VzLPRClient_StartRealPlay(lprHandle, pictureBox3.Handle);
                pictureBox3.Tag = lprHandle;

                // 设置车牌识别结果回调
                m_PlateResultCB2 = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
                VzClientSDK.VzLPRClient_SetPlateInfoCallBack(lprHandle, m_PlateResultCB2, IntPtr.Zero, 1);
            }

        }
        private int OnPlateResult(int handle, IntPtr pUserData,
                                                IntPtr pResult, uint uNumPlates,
                                                VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType,
                                                IntPtr pImgFull,
                                                IntPtr pImgPlateClip)
        {
            if (eResultType != VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME)
            {
                VzClientSDK.TH_PlateResult result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
                string strLicense = new string(result.license);

                VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInfo = new VzClientSDK.VZ_LPR_MSG_PLATE_INFO();
                plateInfo.plate = strLicense;

                DateTime now = DateTime.Now;
                string sTime = string.Format("{0:yyyyMMddHHmmssffff}", now);

                string strFilePath = m_sAppPath + "\\" + Get_IP(handle) + "\\cap\\";
                if (!Directory.Exists(strFilePath))
                {
                    Directory.CreateDirectory(strFilePath);
                }

                string path = strFilePath + sTime + ".jpg";

                VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 100);
                plateInfo.img_path = path;

                int size = Marshal.SizeOf(plateInfo);
                IntPtr intptr = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(plateInfo, intptr, true);

                Win32API.PostMessage(hwndMain, MSG_PLATE_INFO, (int)intptr, handle);
            }

            return 0;
        }

        protected override void DefWndProc(ref Message m)
        {
            IntPtr intptr;
            VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInfo;
            VzClientSDK.VZ_LPR_DEVICE_INFO deviceInfo;

            int handle = 0;

            switch (m.Msg)
            {
                case MSG_PLATE_INFO:
                    intptr = (IntPtr)m.WParam.ToInt32();
                    handle = m.LParam.ToInt32();
                    if (intptr != null)
                    {
                        // VzClientSDK.VzLPRClient_SetIOOutputAuto(m_hLPRClient, 0, 500);
                        //根据句柄获取设备IP
                        byte[] strDecIP = new byte[32];
                        int max_count = 32;
                        int ret = VzClientSDK.VzLPRClient_GetDeviceIP(handle, ref strDecIP[0], max_count);
                        string strIP = System.Text.Encoding.Default.GetString(strDecIP);
                        strIP = strIP.TrimEnd('\0');

                        plateInfo = (VzClientSDK.VZ_LPR_MSG_PLATE_INFO)Marshal.PtrToStructure(intptr, typeof(VzClientSDK.VZ_LPR_MSG_PLATE_INFO));

                        if (handle == GetPicBox1Handle())
                        {
                            // 显示车牌号
                            if (plateInfo.plate != "")
                            {
                                // lblPlate.Text = strIP+"- " + plateInfo.plate;
                            }

                            // 显示图片
                            if (plateInfo.img_path != "")
                            {
                                pictureBox2.Image = Image.FromFile(plateInfo.img_path);
                            }

                        }
                        else
                        {
                            // 显示车牌号
                            if (plateInfo.plate != "")
                            {
                                //  lblPlate2.Text = strIP + "- "+ plateInfo.plate;
                            }

                            // 显示图片
                            if (plateInfo.img_path != "")
                            {
                                pictureBox4.Image = Image.FromFile(plateInfo.img_path);
                            }
                        }

                        ShowDetail(plateInfo,strIP);

                        Marshal.FreeHGlobal(intptr);
                    }

                    break;

                case MSG_DEVICE_INFO:
                    intptr = (IntPtr)m.WParam.ToInt32();
                    if (intptr != null)
                    {
                        deviceInfo = (VzClientSDK.VZ_LPR_DEVICE_INFO)Marshal.PtrToStructure(intptr, typeof(VzClientSDK.VZ_LPR_DEVICE_INFO));
                        ShowDevice(deviceInfo.device_ip, deviceInfo.serial_no);

                        Marshal.FreeHGlobal(intptr);

                    }
                    break;

                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }
        //触发结果显示

        private void ShowDetail(VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInformation,string strIP)
        {
            Lic_Retured_value Retured_LIC = new Lic_Retured_value();

            Retured_LIC.Licence_Num = strIP + "-" + plateInformation.plate;
            Retured_LIC.Image_path = plateInformation.img_path;
            Retured_LIC.Time_income = DateTime.Now.ToLocalTime().ToString(); ;

            string json1 = JsonHelper.SerializeObject(Retured_LIC); //序列化
            Lic_Retured_value Retured_Licence = JsonHelper.DeserializeJsonToObject<Lic_Retured_value>(json1);

            ListViewItem item = new ListViewItem(strIP);
            item.SubItems.Add(Retured_Licence.Licence_Num.Substring(Retured_Licence.Licence_Num.Length - 7));
            item.SubItems.Add(Retured_Licence.Time_income);

            this.listView1.Items.Add(item);
            int countPlateMsg = this.listView1.Items.Count;
            int flagItem = 50;//超过50条，删除一条
            if (countPlateMsg > flagItem)
            {
                this.listView1.Items[countPlateMsg - 1].Remove();
            }


            if (listBox1.Items.Count < 20)  //信息显示
                listBox1.Items.Add("车牌号：" + Retured_Licence.Licence_Num.Substring(Retured_Licence.Licence_Num.Length - 7) + "  进场时间：" + Retured_Licence.Time_income);
            else
                listBox1.Items.Clear();

        }
        public void ShowDevice(string pStrDev, string serialNO)
        {
            TreeNode node = new TreeNode(pStrDev);
            node.Tag = serialNO;
            dev_treeview.Nodes.Add(node);
            dev_treeview.Sort();
        }

        private int GetPicBox3Handle()
        {
            int handle = 0;

            if (pictureBox3.Tag != null)
            {
                string sHandle = pictureBox3.Tag.ToString();
                handle = Int32.Parse(sHandle);
            }

            return handle;
        }

        private void stoprealplaybtn_Click(object sender, EventArgs e)
        {
            if (m_bFirst)
            {
                if (m_nPlayHandle > 0)
                {
                    int ret = VzClientSDK.VzLPRClient_StopRealPlay(m_nPlayHandle);
                    m_nPlayHandle = 0;
                }

                int lprHandle = GetPicBox1Handle();
                if (lprHandle > 0)
                {
                    VzClientSDK.VzLPRClient_SetPlateInfoCallBack(lprHandle, null, IntPtr.Zero, 0);
                }
                lblPlate.Text = "";
                Pic1Close();
                Pic2Close();
            }
            else
            {
                if (m_nPlayHandle2 > 0)
                {
                    int ret = VzClientSDK.VzLPRClient_StopRealPlay(m_nPlayHandle2);
                    m_nPlayHandle2 = 0;
                }

                int lprHandle2 = GetPicBox3Handle();
                if (lprHandle2 > 0)
                {
                    VzClientSDK.VzLPRClient_SetPlateInfoCallBack(lprHandle2, null, IntPtr.Zero, 0);
                }
                lblPlate2.Text = "";
                Pic3Close();
                Pic4Close();
            }


        }

        private void btnConnStat_Click(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            byte stat = 0;

            VzClientSDK.VzLPRClient_IsConnected(lprHandle, ref stat);

            byte[] strDecIP = new byte[32];
            int max_count = 32;
            int ret = VzClientSDK.VzLPRClient_GetDeviceIP(lprHandle, ref strDecIP[0], max_count);
            string strIP = System.Text.Encoding.Default.GetString(strDecIP);
            strIP = strIP.TrimEnd('\0');


            if (stat == 1)
            {
                toolStripStatusLabel1.Text = strIP + "号牌机连接正常";
            }
            else
            {
                toolStripStatusLabel1.Text = strIP + "号牌机连接断开";
            }
        }

        private void recordbtn_Click(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            resetrecordtime = new System.Timers.Timer(1000 * 20);
            resetrecordtime.Elapsed += new System.Timers.ElapsedEventHandler(RecordReset);
            resetrecordtime.AutoReset = true;
            resetrecordtime.Enabled = true;

            string strFilePath = m_sAppPath + "\\" + Get_IP(lprHandle) + "\\Video";
            if (!Directory.Exists(strFilePath))
            {
                Directory.CreateDirectory(strFilePath);
            }
            string szPath = strFilePath + "\\" + DateTime.Now.Year.ToString() +
                DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() +
                DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString() +
                ".avi";
            VzClientSDK.VzLPRClient_SaveRealData(lprHandle, szPath);
            recordbtn.Enabled = false;
            stoprecordbtn.Enabled = true;
        }

        public void RecordReset(object source, System.Timers.ElapsedEventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            VzClientSDK.VzLPRClient_StopSaveRealData(lprHandle);
            string strFilePath = m_sAppPath + "\\" + Get_IP(lprHandle) + "Video";
            string szPath = strFilePath + "\\" + DateTime.Now.Year.ToString() +
                DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() +
                DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() +
                DateTime.Now.Second.ToString() + ".avi";
            VzClientSDK.VzLPRClient_SaveRealData(lprHandle, szPath);

        }

        private void stoprecordbtn_Click(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            VzClientSDK.VzLPRClient_StopSaveRealData(lprHandle);
            resetrecordtime.Close();
            stoprecordbtn.Enabled = false;
            recordbtn.Enabled = true;
        }

        private void btnVideoCfg_Click(object sender, EventArgs e)
        {
            //Thread th = new Thread(ReadDoc);
            //th.IsBackground = true;
            //th.Start();
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            int board_type = 0;
            VzClientSDK.VzLPRClient_GetHwBoardType(lprHandle, ref board_type);
            if (board_type == 3)
            {
                RVideoCfg_Form from = new RVideoCfg_Form();
                from.StartPosition = FormStartPosition.CenterScreen;
                from.SetLPRHandle(lprHandle);
                from.Show();
            }
            else
            {
                VideoCfg_Form from = new VideoCfg_Form();
                from.StartPosition = FormStartPosition.CenterScreen;
                from.SetLPRHandle(lprHandle);
                from.Show();
            }

        }
        private void ReadDoc()
        {

            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            int board_type = 0;
            VzClientSDK.VzLPRClient_GetHwBoardType(lprHandle, ref board_type);
            if (board_type == 3)
            {
                RVideoCfg_Form from = new RVideoCfg_Form();
                from.StartPosition = FormStartPosition.CenterScreen;
                from.SetLPRHandle(lprHandle);
                from.Show();
            }
            else
            {
                VideoCfg_Form from = new VideoCfg_Form();
                from.StartPosition = FormStartPosition.CenterScreen;
                from.SetLPRHandle(lprHandle);
                from.Show();
            }

        }

        private void btnRuleCfg_Click(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            RuleCfg_Form from = new RuleCfg_Form();
            from.StartPosition = FormStartPosition.CenterScreen;
            from.SetLPRHandle(lprHandle);
            from.Show();
        }

        private void m_btnBaseConfig_Click(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            BaseConfig_From configform = new BaseConfig_From();
            configform.StartPosition = FormStartPosition.CenterScreen;
            configform.SetLPRHandle(lprHandle);
            configform.ShowDialog();
        }

        private void radledauto_CheckedChanged(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            VzClientSDK.VzLPRClient_SetLEDLightControlMode(lprHandle, VzClientSDK.VZ_LED_CTRL.VZ_LED_AUTO);
        }

        private void radledon_CheckedChanged(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            VzClientSDK.VzLPRClient_SetLEDLightControlMode(lprHandle, VzClientSDK.VZ_LED_CTRL.VZ_LED_MANUAL_ON);

        }

        private void radledoff_CheckedChanged(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            VzClientSDK.VzLPRClient_SetLEDLightControlMode(lprHandle, VzClientSDK.VZ_LED_CTRL.VZ_LED_MANUAL_OFF);

        }

        private void ledbar_Scroll(object sender, EventArgs e)
        {
            int lprHandle = GetSeleHandle();
            if (lprHandle == 0)
            {
                toolStripStatusLabel1.Text = "请选择一台列表中的设备";
                return;
            }

            int nValue = ledbar.Value - 1;

            int nLevelNow = 0;
            int nLevelMax = 0;

            VzClientSDK.VzLPRClient_GetLEDLightStatus(lprHandle, ref nLevelNow, ref nLevelMax);
            m_nLastLEDLevel = nLevelNow;
            if (nValue != nLevelNow)
            {
                VzClientSDK.VzLPRClient_SetLEDLightLevel(lprHandle, nValue);
                m_nLastLEDLevel = nValue;
            }
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            Color c = Color.FromArgb(255, 220, 220, 220);
            pictureBox1.BackColor = c;

            pictureBox3.BackColor = m_originalColor;
            m_bFirst = true;
        }

        private string Get_IP(int lprHandle)
        {
            byte[] strDecIP = new byte[32];
            int max_count = 32;
            int ret = VzClientSDK.VzLPRClient_GetDeviceIP(lprHandle, ref strDecIP[0], max_count);
            string strIP = System.Text.Encoding.Default.GetString(strDecIP);
            strIP = strIP.TrimEnd('\0');
            return strIP;
        }

        private void pictureBox3_Click(object sender, EventArgs e)
        {
            pictureBox1.BackColor = m_originalColor;

            Color c = Color.FromArgb(255, 220, 220, 220);
            pictureBox3.BackColor = c;
            m_bFirst = false;
        }
    }

    public class Win32API
    {
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("User32.dll", EntryPoint = "FindWindowEx")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);

        /// <summary>
        /// 自定义的结构
        /// </summary>
        public struct My_lParam
        {
            public int i;
            public string s;
        }
        /// <summary>
        /// 使用COPYDATASTRUCT来传递字符串
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }
        //消息发送API
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(
            IntPtr hWnd,        // 信息发往的窗口的句柄
           int Msg,            // 消息ID
            int wParam,         // 参数1
            int lParam          //参数2
        );


        //消息发送API
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(
            IntPtr hWnd,        // 信息发往的窗口的句柄
           int Msg,            // 消息ID
            int wParam,         // 参数1
            ref My_lParam lParam //参数2
        );

        //消息发送API
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(
            IntPtr hWnd,        // 信息发往的窗口的句柄
           int Msg,            // 消息ID
            int wParam,         // 参数1
            ref COPYDATASTRUCT lParam  //参数2
        );

        //消息发送API
        [DllImport("User32.dll", EntryPoint = "PostMessage")]
        public static extern int PostMessage(
            IntPtr hWnd,        // 信息发往的窗口的句柄
           int Msg,            // 消息ID
            int wParam,         // 参数1
            int lParam            // 参数2
        );


        //消息发送API
        [DllImport("User32.dll", EntryPoint = "PostMessage")]
        public static extern int PostMessage(
            IntPtr hWnd,        // 信息发往的窗口的句柄
           int Msg,            // 消息ID
            int wParam,         // 参数1
            ref My_lParam lParam //参数2
        );

        //异步消息发送API
        [DllImport("User32.dll", EntryPoint = "PostMessage")]
        public static extern int PostMessage(
            IntPtr hWnd,        // 信息发往的窗口的句柄
           int Msg,            // 消息ID
            int wParam,         // 参数1
            ref COPYDATASTRUCT lParam  // 参数2
        );

    }
}
